;; The following uses a mixture of 
;;     http://mmcgrana.github.com/2010/07/develop-deploy-clojure-web-applications.html
;;       (most of the code)
;;     https://github.com/weavejester/compojure/wiki/Getting-Started
;;       (necessary, since the first one is slightly out of date)
(ns tala.core
  (:use tala.middleware)
  (:use tala.info)
  (:use tala.util)
  (:use compojure.core)
  (:require [compojure.route :as route]
            [compojure.handler :as handler])
  (:use ring.middleware.reload)
  (:use ring.middleware.stacktrace)
  (:use ring.util.response)
  (:use hiccup.core)
  ;; (:use hiccup.page-helpers)
  )

;; Distinguish between production and development versions
(def development?
  (= "development" (get (System/getenv) "TALA_MODE")))
(def production?
  (not development?))

;; This connection, and these credentials, will work only within the ROE firewall.
(def db
  (if production?
    {:classname "org.postgresql.Driver"
     :subprotocol "postgresql"
     :subname "//localhost/astrodabis"
     :user "astrodabis"
     :password "astroDABIS*"}
    {:classname "org.sqlite.JDBC"
     :subprotocol "sqlite"
     :subname "test/data/testdb.db"}))

;; Aggravatingly, Compojure doesn't accept dots in its path-segment
;; regexp, heaven knows why (see https://github.com/weavejester/compojure/issues/42).
;; This is the definition from RFC 3986:
;;   segment       = *pchar
;;   pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
;;   unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
;;   pct-encoded = "%" HEXDIG HEXDIG
;;   sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
;;               / "*" / "+" / "," / ";" / "="
(def path-segment-re #"[A-Za-z0-9%._~!$&'()*+,;=-]*")
;(def email-address-re #"[A-Za-z0-9.+-]+@[A-Za-z0-9-.]+")
(def user-re #"[A-Za-z][A-Za-z0-9.-]*") ;correct?
(def tag-re #"[a-zA-Z0-9-]+")

;; FIXME: in various places below we've (had to) wired the deployment
;; prefix.  This isn't nice.  Does
;; <https://github.com/weavejester/compojure-example/blob/master/src/compojure/example/routes.clj>
;; help, by showing the handler wrapped in (wrap-base-url) from hiccup.middleware ?

(defroutes all-routes
  (GET "/" []
       (redirect "/tala/index.html"))   ;FIXME: wired deployment prefix
  (GET "/tag" []                     ;bind param 'tag' to tag
       (respond-html "Enter a tag"
                       [:form {:method "get" :action "/tala/tag"}
                        [:p "Tag: "]
                        [:input {:type "text" :name "tag"}]
                        [:input.action {:type "submit" :value "Find"}]]))
  (GET "/tag/" []
       (redirect "/tala/tag"))          ;FIXME: wired deployment prefix
  (GET ["/tag/:tag" :tag tag-re]
       {{accept "accept"} :headers
        {tag :tag} :params}
       (search-for-tagged-objects db tag accept))
  ;; (GET ["/id/u/:user" :user user-re]
  ;;      {{accept "accept"} :headers
  ;;       {user :user} :params}
  ;;      (loop [s (parse-accept-header accept)]
  ;;        (if (not s)
  ;;          (status (response "No acceptable response for accept header") 406)
  ;;          (case (first s)
  ;;            "text/html" (status (redirect (str "/u/" user)) 303)
  ;;            ("text/turtle" "application/rdf+xml") (status (redirect (str "/data/u/" user)) 303)
  ;;            (recur (rest s))))))
  ;; (GET ["/data/u/:user" :user user-re]
  ;;      {{accept "accept"} :headers
  ;;       {user :user} :params}
  ;;      ;; Hmm: we're using the same underlying function for /data/u
  ;;      ;; and /u -- ought we to?  If the user dereferences /data/u in
  ;;      ;; a browser, oughtn't we to prefer, say text/* (which
  ;;      ;; would mean text/turtle)
  ;;      (describe-user db user accept))
  ;; (GET ["/u/:user" :user user-re]
  ;;      {{accept "accept"} :headers
  ;;       {user :user} :params}
  ;;      (describe-user db user accept))
  ;; (GET ["/u/:user/:tag" :user user-re :tag tag-re]
  ;;      {{accept "accept"} :headers
  ;;       {tag :tag user :user} :params}
  ;;      (search-for-tagged-objects-by-user db tag user accept))
  (GET "/:any" [any]
       (respond-html "Top"
                     [:div [:p "Top: " any]]))
  ;;(route/files "/")
  (route/resources "/")
  (route/not-found "Not found (eek)"))

;; (defroutes tomcat-routes                ;FIXME: this is wiring the deployment location -- better way?
;;   (context "/tala" [] all-routes)
;;   (GET "/:any" [any]
;;        (respond-html "Tomcats"
;;                      [:p "Tomcats put " any " in your food"]))
;;   (route/not-found "Tomcats spray piss in your face"))

(def handler
  (-> #'all-routes
      (wrap-request-logging)
      ;(wrap-if development? wrap-reload '[tala.middleware tala.core])
      (wrap-reload '[tala.middleware tala.core])
      (wrap-bounce-favicon)
      (wrap-exception-logging)
      (wrap-if production? wrap-failsafe)
      (wrap-if development? wrap-stacktrace)))

;; the following may not be necessary
(def app
     (handler/site handler))

